package com.pig4cloud.pig.module.service.product.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.common.core.exception.TransactionalException;
import com.pig4cloud.pig.common.core.util.DateUtils;
import com.pig4cloud.pig.common.core.util.MathUtil;
import com.pig4cloud.pig.common.core.util.OrderUtil;
import com.pig4cloud.pig.common.core.wx.WxAppPay;
import com.pig4cloud.pig.common.core.yilianprint.LAVApi;
import com.pig4cloud.pig.common.security.service.PigUser;
import com.pig4cloud.pig.module.api.entity.dto.MerTableDto;
import com.pig4cloud.pig.module.api.entity.dto.OrderRestaurantSettleDto;
import com.pig4cloud.pig.module.api.entity.excel.ProductOrderExcel;
import com.pig4cloud.pig.module.api.entity.excel.ProductOrderMerDetailExcel;
import com.pig4cloud.pig.module.api.entity.excel.ProductOrderMerTotalExcel;
import com.pig4cloud.pig.module.api.entity.mer.*;
import com.pig4cloud.pig.module.api.entity.product.*;
import com.pig4cloud.pig.module.api.vo.MonthMoneyVo;
import com.pig4cloud.pig.module.mapper.mer.*;
import com.pig4cloud.pig.module.mapper.product.ProductOrderMapper;
import com.pig4cloud.pig.module.mapper.product.ProductOrderTableMapper;
import com.pig4cloud.pig.module.service.mer.IMerPrinterService;
import com.pig4cloud.pig.module.service.mer.IMerSelfVipService;
import com.pig4cloud.pig.module.service.mer.IMerTableService;
import com.pig4cloud.pig.module.service.product.*;
import com.pig4cloud.pig.module.service.wx.IWxTemplateService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 订单Service业务层处理
 *
 * @author ruoyi
 * @date 2021-08-11
 */
@Service
public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements IProductOrderService {

	@Resource
	private ProductOrderMapper orderMapper;
	@Resource
	private MerMapper merMapper;
	@Resource
	private MerTableMapper merTableMapper;
	@Resource
	private MerPrinterMapper merPrinterMapper;
	@Resource
	private IMerPrinterService merPrinterService;
	@Resource
	private IWxTemplateService wxTemplateService;
	@Resource
	private IProductOrderInfoService productOrderInfoService;
	@Resource
	private MerSelfVipMapper merSelfVipMapper;
	@Resource
	private MerSelfVipRechargeRecordMapper selfVipRechargeRecordMapper;
	@Resource
	private IMerSelfVipService merSelfVipService;
	@Resource
	private IProductOrderTableService productOrderTableService;
	@Resource
	private ProductOrderTableMapper productOrderTableMapper;
	@Resource
	private IProductCartService cartService;
	@Resource
	private IMerTableService merTableService;

	@Resource
	private IProductService productService;


	@Value("${web.wx_refund_notify_url}")
	private String wx_refund_notify_url;//微信支付退款的回调地址
	@Value("${web.keyPath}")
	private String keyPath;//微信支付的回调地址

	@Value("${web.mch_id}")
	private String mch_id;

	@Value("${web.appid}")
	private String appid;
	@Value("${web.secret}")
	private String secret;

	@Value("${web.api_key}")
	private String api_key;


	@Override
	@Transactional
	public int settleMerOrder(PigUser sysUser, OrderRestaurantSettleDto settleDto) {
		int ret = 0;
		try{
			double money = 0.00;
			if (settleDto.getCardNum()!=null){
				if (settleDto.getVipMoney()!=0){
					MerSelfVip merSelfVip = merSelfVipService.selectByUniqueColumn("card_num", settleDto.getCardNum());
					if (settleDto.getVipMoney()>settleDto.getTotalPrice().doubleValue()){
						money= settleDto.getVipMoney()-settleDto.getTotalPrice().doubleValue();
					}else if (settleDto.getVipMoney()<=settleDto.getTotalPrice().doubleValue()){
						money=0.00;
					}
					merSelfVip.setMoney(settleDto.getTotalPrice().doubleValue());
					merSelfVip.setAccountMoney(BigDecimal.valueOf(money));
//                merSelfVipService.updateById(merSelfVip);
					ret = merSelfVipService.charge(merSelfVip, sysUser);
					if(ret <= 0){
						throw new TransactionalException("merSelfVipService charge error ");
					}
				}
			}
			ret = tableSettleOrder(settleDto,sysUser);
			if(ret <= 0){
				throw new TransactionalException("tableSettleOrder error ");
			}

			ProductOrderTable table = new ProductOrderTable();
			Date date = new Date();
			table.setTableId(Long.valueOf(settleDto.getTableId()));
			if (settleDto.getXianjin() == 1 && settleDto.getRemark() == null){
				table.setRemark("现金结算");
			}else if (settleDto.getXianjin() == 1 && settleDto.getRemark() != null){
				table.setRemark(settleDto.getRemark()+",现金结算");
			}else if (settleDto.getRemark()!=null){
				table.setRemark(settleDto.getRemark());
			}
			table.setPayTime(date);
			table.setTotalPrice(settleDto.getTotalPrice());
			table.setPayPrice(settleDto.getPayPrice());
			ret = productOrderTableMapper.insert(table);
			if(ret <= 0){
				throw new TransactionalException("productOrderTableMapper insert error ");
			}

			// 修改购物车的 支付状态 is_pay = 0 如果不修改  餐桌下单的时候 会影响 餐具抽纸的 自动添加
			MerTable merTable = merTableService.findById(settleDto.getTableId());
			if(merTable != null){
				boolean bl = cartService.update(new LambdaUpdateWrapper<ProductCart>()
					.set(ProductCart::getIsPay, 1)
					.eq(ProductCart::getMerId,  merTable.getMerId())
					.eq(ProductCart::getTableId, merTable.getId())
					.eq(ProductCart::getIsPay, 0)
				);
				ret = 1;
			}

		}catch (Exception e){
			e.printStackTrace();
			throw new TransactionalException("productOrderTableMapper system error ");
		}
		return ret;
	}

	@Override
	public Double selectTotalMoneyByTime(Map<String,Object> map) {
		return orderMapper.selectTotalMoneyByTime(map);
	}

	@Override
	public Double selectFenRunPlatform(Map<String, Object> map) {
		return orderMapper.selectFenRunPlatform(map);
	}

	@Override
	public Double selectFenRunProperty(Map<String, Object> map) {
		return orderMapper.selectFenRunProperty(map);
	}

	@Override
	public Double selectFenRunEstate(Map<String, Object> map) {
		return orderMapper.selectFenRunEstate(map);
	}

	@Override
	public Map<String, Object>  selectFenRunMer(Map<String, Object> map) {
		return orderMapper.selectFenRunMer(map);
	}

	@Override
	public List<MonthMoneyVo> selectTotalMoneyByDay(Map<String, Object> map) {
		return orderMapper.selectTotalMoneyByDay(map);
	}

	@Override
	public List<ProductOrderExcel> selectExcelListByTime(Map<String, Object> map) {
		return orderMapper.selectExcelListByTime(map);
	}

	@Override
	public List<ProductOrderMerTotalExcel> selectExcelMerTotalListByTime(Map<String, Object> map) {
		return orderMapper.selectExcelMerTotalListByTime(map);
	}

	@Override
	public List<ProductOrderMerDetailExcel> selectExcelMerDetailListByTime(Map<String, Object> map) {
		return orderMapper.selectExcelMerDetailListByTime(map);
	}

	@Override
	public List<ProductOrderExcel> selectPageExcelListByTime(Page<ProductOrderExcel> page, Map<String, Object> map) {
		return orderMapper.selectExcelListByTime(page,map);
	}

	@Override
	public ProductOrderExcel selectTongjiByEstateId(Map<String, Object> map) {
		return orderMapper.selectTongjiByEstateId(map);
	}

	@Override
	public int refundOp(ProductOrder order) {
		int ret = 0;
		try{
			String tradeNo = OrderUtil.getPayNo();
			order.setRefundOutTradeNo(tradeNo);
			Map<String,Object> map = new HashMap<>();
			WxAppPay wxAppPay = new WxAppPay(wx_refund_notify_url, secret, appid, mch_id,api_key);
			Map<String, String> retRequest = wxAppPay.refundPayAPI(order.getOutTradeNo(),order.getPayPrice(),order.getPayPrice(),order.getRefundOutTradeNo(),keyPath);
			if(retRequest.containsKey("return_code")){
				String result_code = retRequest.get("result_code");
				String err_code_des = retRequest.containsKey("err_code_des") ? retRequest.get("err_code_des") : "";
				map.put("result_code",result_code);
				map.put("err_code_des",err_code_des);
				if(result_code.equals("SUCCESS")){
					order.setRefundStatus(7);//支付成功
				}
			}
			ret = orderMapper.updateById(order);
		}catch (Exception e){
			e.printStackTrace();
		}
		return ret;
	}

	@Override
	public void printAddAll(List<ProductOrderInfo> orderInfos) {

		long orderId = 0;
		//按照类型分组，  凉菜一类  热菜一类  烧烤一类
		List<ProductOrderInfo> infoListType0 = new ArrayList<>();
		List<ProductOrderInfo> infoListType1 = new ArrayList<>();
		List<ProductOrderInfo> infoListType2 = new ArrayList<>();
		if(CollUtil.isNotEmpty(orderInfos)){
			for (ProductOrderInfo info : orderInfos){
				// 凉菜   热菜  烧烤 才在后厨打印
				if(info.getDishType()!= null){
					if(info.getDishType() == 0 ){
						infoListType0.add(info);
					} else if(info.getDishType() == 1){
						infoListType1.add(info);
					} else if(info.getDishType() == 2){
						infoListType2.add(info);
					}
				}
			}
			orderId = orderInfos.get(0).getOrderId();
		}

		Mer mer = null;
		ProductOrder order = orderMapper.selectById(orderId);
		if(order!= null){
			mer = merMapper.selectById(order.getMerId());
		}

		if(mer!= null){
			MerTable merTable = merTableMapper.selectById(order.getMerTableId());
			QueryWrapper<MerPrinter> qwPrinter = new QueryWrapper<>();
			qwPrinter.eq("mer_id",order.getMerId());
			qwPrinter.eq("state",1);
			qwPrinter.eq("print_status",1);
			List<MerPrinter> printers = merPrinterService.list(qwPrinter);
			if(CollUtil.isNotEmpty(printers)){
				for (MerPrinter printer : printers){
					if(printer.getIsPrintAll() == 1){
						printerAll(order, mer, merTable, printer,orderInfos);
					}else{
						//打印凉菜
						if(infoListType0.size() > 0 && printer.getDishType()==0){
							printerInfo(order, mer, merTable, printer,infoListType0);
						}
						//打印热菜
						if(infoListType1.size() > 0 && printer.getDishType()==1){
							printerInfo(order, mer, merTable, printer,infoListType1);
						}
						//打印烧烤
						if(infoListType2.size() > 0 && printer.getDishType()==2){
							printerInfo(order, mer, merTable, printer,infoListType2);
						}
					}
				}
			}
		}
	}

	@Override
	public void print(ProductOrder order) {

		MerTable merTable = merTableMapper.selectById(order.getMerTableId());
		Mer mer = merMapper.selectById(order.getMerId());

		List<ProductOrderInfo> listInfo = productOrderInfoService.selectListByOrderId(order.getId());
		//按照类型分组，  凉菜一类  热菜一类  烧烤一类
		List<ProductOrderInfo> infoListType0 = new ArrayList<>();
		List<ProductOrderInfo> infoListType1 = new ArrayList<>();
		List<ProductOrderInfo> infoListType2 = new ArrayList<>();
		if(CollUtil.isNotEmpty(listInfo)){

			for (ProductOrderInfo info : listInfo){
				// 凉菜   热菜  烧烤 才在后厨打印
				if(info.getDishType()!= null) {
					if (info.getDishType() == 0) {
						infoListType0.add(info);
					} else if (info.getDishType() == 1) {
						infoListType1.add(info);
					} else if (info.getDishType() == 2) {
						infoListType2.add(info);
					}
				}
			}
		}

		QueryWrapper<MerPrinter> qwPrinter = new QueryWrapper<>();
		qwPrinter.eq("mer_id",order.getMerId());
		qwPrinter.eq("state",1);
		qwPrinter.eq("print_status",1);
		List<MerPrinter> printers = merPrinterService.list(qwPrinter);
		if(CollUtil.isNotEmpty(printers)){
			for (MerPrinter printer : printers){
				if(printer.getIsPrintAll() == 1){
					printerAll(order, mer, merTable, printer,listInfo);
				}else{
					//打印凉菜
					if(infoListType0.size() > 0 && printer.getDishType()==0){
						printerInfo(order, mer, merTable, printer,infoListType0);
					}
					//打印热菜
					if(infoListType1.size() > 0 && printer.getDishType()==1){
						printerInfo(order, mer, merTable, printer,infoListType1);
					}
					//打印烧烤
					if(infoListType2.size() > 0 && printer.getDishType()==2){
						printerInfo(order, mer, merTable, printer,infoListType2);
					}
				}
			}
		}
	}

	@Override
	public void print0(ProductOrder order) {
		MerTable merTable = merTableMapper.selectById(order.getMerTableId());
		Mer mer = merMapper.selectById(order.getMerId());

		List<ProductOrderInfo> listInfo = productOrderInfoService.selectListByOrderId(order.getId());
		//按照类型分组，  凉菜一类  热菜一类  烧烤一类
		List<ProductOrderInfo> infoListType0 = new ArrayList<>();
		List<ProductOrderInfo> infoListType1 = new ArrayList<>();
		List<ProductOrderInfo> infoListType2 = new ArrayList<>();
		if(CollUtil.isNotEmpty(listInfo)){

			for (ProductOrderInfo info : listInfo){
				// 凉菜   热菜  烧烤 才在后厨打印

				if(info.getDishType()!= null) {
					if (info.getDishType() == 0) {
						infoListType0.add(info);
					} else if (info.getDishType() == 1) {
						infoListType1.add(info);
					} else if (info.getDishType() == 2) {
						infoListType2.add(info);
					}
				}
			}
		}

		QueryWrapper<MerPrinter> qwPrinter = new QueryWrapper<>();
		qwPrinter.eq("mer_id",order.getMerId());
		qwPrinter.eq("state",1);
		qwPrinter.eq("print_status",1);
//		qwPrinter.eq("dish_type",0);
		List<MerPrinter> printers = merPrinterService.list(qwPrinter);
		if(CollUtil.isNotEmpty(printers)){
			for (MerPrinter printer : printers){
				//按照类型分组，  凉菜一类
				//打印凉菜
//				if(infoListType0.size() > 0 && printer.getDishType()==0){
//					printerInfo(order, mer, merTable, printer,infoListType0);
//				}
				if(printer.getDishType() == 0){
					List<ProductOrderInfo> infos = new ArrayList<>();
					if(infoListType0.size() > 0){
						infos.addAll(infoListType0);
					}
					if(infoListType1.size() > 0){
						infos.addAll(infoListType1);
					}
					if(infos.size() > 0){
						printerInfo(order, mer, merTable, printer, infos);
					}
				}

			}
		}
	}

	@Override
	public void print1(ProductOrder order) {
		MerTable merTable = merTableMapper.selectById(order.getMerTableId());
		Mer mer = merMapper.selectById(order.getMerId());

		List<ProductOrderInfo> listInfo = productOrderInfoService.selectListByOrderId(order.getId());
		//按照类型分组，  凉菜一类  热菜一类  烧烤一类
		List<ProductOrderInfo> infoListType0 = new ArrayList<>();
		List<ProductOrderInfo> infoListType1 = new ArrayList<>();
		List<ProductOrderInfo> infoListType2 = new ArrayList<>();
		if(CollUtil.isNotEmpty(listInfo)){

			for (ProductOrderInfo info : listInfo){
				// 凉菜   热菜  烧烤 才在后厨打印

				if(info.getDishType()!= null) {
					if (info.getDishType() == 0) {
						infoListType0.add(info);
					} else if (info.getDishType() == 1) {
						infoListType1.add(info);
					} else if (info.getDishType() == 2) {
						infoListType2.add(info);
					}
				}
			}
		}

		QueryWrapper<MerPrinter> qwPrinter = new QueryWrapper<>();
		qwPrinter.eq("mer_id",order.getMerId());
		qwPrinter.eq("state",1);
		qwPrinter.eq("print_status",1);
		qwPrinter.eq("dish_type",1);
		List<MerPrinter> printers = merPrinterService.list(qwPrinter);
		if(CollUtil.isNotEmpty(printers)){
			for (MerPrinter printer : printers){
				//打印凉菜
//				if(infoListType1.size() > 0  && printer.getDishType() == 1){
//					printerInfo(order, mer, merTable, printer, infoListType1);
//				}
				if(printer.getDishType() == 1){
					List<ProductOrderInfo> infos = new ArrayList<>();
					if(infoListType0.size() > 0){
						infos.addAll(infoListType0);
					}
					if(infoListType1.size() > 0){
						infos.addAll(infoListType1);
					}
					if(infoListType2.size() > 0){
						infos.addAll(infoListType2);
					}
					if(infos.size() > 0){
						printerInfo(order, mer, merTable, printer, infos);
					}
				}

			}
		}
	}

	@Override
	public void print2(ProductOrder order) {
		MerTable merTable = merTableMapper.selectById(order.getMerTableId());
		Mer mer = merMapper.selectById(order.getMerId());

		List<ProductOrderInfo> listInfo = productOrderInfoService.selectListByOrderId(order.getId());
		//按照类型分组，  凉菜一类  热菜一类  烧烤一类
		List<ProductOrderInfo> infoListType0 = new ArrayList<>();
		List<ProductOrderInfo> infoListType1 = new ArrayList<>();
		List<ProductOrderInfo> infoListType2 = new ArrayList<>();
		if(CollUtil.isNotEmpty(listInfo)){

			for (ProductOrderInfo info : listInfo){
				// 凉菜   热菜  烧烤 才在后厨打印
				if(info.getDishType()!= null) {
					if (info.getDishType() == 0) {
						infoListType0.add(info);
					} else if (info.getDishType() == 1) {
						infoListType1.add(info);
					} else if (info.getDishType() == 2) {
						infoListType2.add(info);
					}
				}
			}
		}

		QueryWrapper<MerPrinter> qwPrinter = new QueryWrapper<>();
		qwPrinter.eq("mer_id",order.getMerId());
		qwPrinter.eq("state",1);
		qwPrinter.eq("print_status",1);
		qwPrinter.eq("dish_type",2);
		List<MerPrinter> printers = merPrinterService.list(qwPrinter);
		if(CollUtil.isNotEmpty(printers)){
			for (MerPrinter printer : printers){

				//打印凉菜
//				if(infoListType2.size() > 0 && printer.getDishType() == 2){
//					printerInfo(order, mer, merTable, printer,infoListType2);
//				}

				if(printer.getDishType() == 1){
					List<ProductOrderInfo> infos = new ArrayList<>();
					if(infoListType0.size() > 0){
						infos.addAll(infoListType0);
					}
					if(infoListType1.size() > 0){
						infos.addAll(infoListType1);
					}
					if(infoListType2.size() > 0){
						infos.addAll(infoListType2);
					}
					if(infos.size() > 0){
						printerInfo(order, mer, merTable, printer, infos);
					}
				}

			}
		}
	}

	@Override
	public void printCounter(ProductOrder order) {
		MerTable merTable = merTableMapper.selectById(order.getMerTableId());
		Mer mer = merMapper.selectById(order.getMerId());

		List<ProductOrderInfo> listInfo = productOrderInfoService.selectListByOrderId(order.getId());
		QueryWrapper<MerPrinter> qwPrinter = new QueryWrapper<>();
		qwPrinter.eq("mer_id",order.getMerId());
		qwPrinter.eq("state",1);
		qwPrinter.eq("print_status",1);
		qwPrinter.eq("dish_type",4);
		List<MerPrinter> printers = merPrinterService.list(qwPrinter);
		if(CollUtil.isNotEmpty(printers)) {
			for (MerPrinter printer : printers) {
				if (printer.getIsPrintAll() == 1) {
					printerAll(order, mer, merTable, printer,listInfo);
				}
			}
		}
	}

	@Override
	@Transactional
	public int tableSettleOrder(OrderRestaurantSettleDto settleDto, PigUser sysUser) {
		int ret = 0;
		try{
			Long[] orderIds = settleDto.getOrderIds();

			if(settleDto.getSelfVipId()!= null && settleDto.getSelfVipId() > 0){
				MerSelfVip merSelfVip = merSelfVipMapper.selectById(settleDto.getSelfVipId());
				if(merSelfVip != null){

					MerSelfVipRechargeRecord rechargeRecord = new MerSelfVipRechargeRecord();
					rechargeRecord.setSelfVipId(merSelfVip.getId());
					rechargeRecord.setBeforeMoney(merSelfVip.getAccountMoney());

					double payVipPrice = settleDto.getSelfPayPrice().doubleValue();
					double accountMoney = merSelfVip.getAccountMoney().doubleValue();
					double leftMoney = accountMoney - payVipPrice;
					if(leftMoney < 0){
						return -1;//余额不足
					}
					merSelfVip.setAccountMoney(new BigDecimal(leftMoney));
					ret = merSelfVipMapper.updateById(merSelfVip);
					if(ret <= 0){
						throw new TransactionalException("merSelfVipMapper updateById error ");
					}

					rechargeRecord.setMerId(merSelfVip.getMerId());
					rechargeRecord.setRechargeMoney(new BigDecimal(payVipPrice));
					rechargeRecord.setVipName(merSelfVip.getRealName());
					rechargeRecord.setVipPhone(merSelfVip.getPhoneNum());
					rechargeRecord.setRechargeType(2);//充值类型 0 - 开会员预充值 1 - 后期充值  2 - 使用
					rechargeRecord.setOpSysUserId(sysUser.getId());
					rechargeRecord.setOpSysUserName(sysUser.getName());
					rechargeRecord.setCreateTime(new Date());
					rechargeRecord.setRemark("会员充值费用");
					ret = selfVipRechargeRecordMapper.insert(rechargeRecord);
					if(ret <= 0){
						throw new TransactionalException("selfVipRechargeRecordMapper insert error");
					}
				}
			}
			if(CollUtil.isNotEmpty(Arrays.asList(orderIds))){
				for (Long orderId : orderIds){
					List<ProductOrderInfo> list = productOrderInfoService.selectListByOrderId(orderId);
					for (ProductOrderInfo info:list){
						if (info.getDishType() != null && info.getDishType()==3 && info.getIsDel()==0){
							Product product = productService.selectByUniqueColumn("id", info.getProductId());
							if (product!=null){
								product.setStock(product.getStock()-info.getCount());
								productService.updateById(product);
							}
						}
					}
					ProductOrder order = orderMapper.selectById(orderId);
					if(order != null){
						order.setStatus(2);
						order.setIsMerCheck(1);
						if (settleDto.getXianjin()==1){
							if (ObjectUtil.isNotEmpty(order.getRemark())){
								order.setRemark(order.getRemark()+",现金结算");
							}else {
								order.setRemark("现金结算");
							}
						}
						if(settleDto.getSelfVipId()!= null && settleDto.getSelfVipId() > 0){
							double discountRate = 0d;
							Mer mer = merMapper.selectById(order.getMerId());
							if(mer != null){
								discountRate = mer.getDiscountRate().doubleValue();
							}
							if(discountRate > 0){
								double payPrice = order.getPayPrice().doubleValue();
								double payPriceNew = payPrice * discountRate / 10;

								order.setSelfVipId(settleDto.getSelfVipId());

								order.setPayPrice(new BigDecimal(payPriceNew));
							}
						}

						ret = orderMapper.updateById(order);
						if(ret <= 0){
							throw new TransactionalException("orderMapper updateById error ");
						}
					}
				}
			}

		}
		catch (Exception e){
			e.printStackTrace();
			throw new TransactionalException("tableSettleOrder system error");
		}
		return ret;
	}

	@Override
	@Transactional
	public int changeOrderTable(MerTableDto merTableDto) {
		int ret = 0;
		try{
			Long[] orderIds = merTableDto.getOrderIds();
			if(CollUtil.isNotEmpty(Arrays.asList(orderIds))){
				for (Long orderId : orderIds){
					ProductOrder order = orderMapper.selectById(orderId);
					if(order != null){
						order.setMerTableId(merTableDto.getTableId());
						ret = orderMapper.updateById(order);
						if(ret <= 0){
							throw new TransactionalException("orderMapper updateById error ");
						}
					}
				}
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return ret;
	}

	/**
	 * 前台总打印机打印订单
	 * @param productOrder
	 */
	private void printerAll(ProductOrder productOrder, Mer mer, MerTable merTable, MerPrinter printer,List<ProductOrderInfo> listInfo){
		if(printer != null){
			String content = getOrderPrintContent(productOrder,mer,merTable,listInfo);
			String client_id = printer.getClientId();
			String access_token = merPrinterService.getPrinterAccessToken(printer.getId());
			String machine_code = printer.getDeviceSn();
			String origin_id = productOrder.getOrderNo();
			String uuid = LAVApi.getuuid();
			long timestamp = new Date().getTime() / 1000;
			//md5(client_id+push_time+client_secret)
			String sign = LAVApi.getSin(client_id , printer.getClientAppKey(),timestamp);

			//String client_id, String access_token, String machine_code, String content, String origin_id, String sign, String id, String timestamp
			String result = LAVApi.print(client_id, access_token, machine_code, content, origin_id, sign, uuid, String.valueOf(timestamp));
			if (result != null && !result.equals("")) {
				//{"error":"0","error_description":"success","body":{"id":"订单号","origin_id":""}}
				JSONObject jsonObject =  JSONUtil.parseObj(result);
				if (jsonObject != null) {
					int error = Integer.parseInt(jsonObject.getStr("error"));
					if(error == 0){
//						productOrder.setPrintState(1);
						System.out.println("打印成功");

						for(ProductOrderInfo info : listInfo){
							info.setPrintState(1);
							if(info.getPrintCount() == null){
								info.setPrintCount(1);
							}else{
								int printCount = info.getPrintCount();
								info.setPrintCount(printCount + 1);
							}
							productOrderInfoService.updateById(info);
						}

					}else{
						System.out.println("打印失败");
//						productOrder.setPrintState(2);
						for(ProductOrderInfo info : listInfo){
							info.setPrintState(2);
							productOrderInfoService.updateById(info);
						}
						if(error == 18){//token 失效
							//重新获取 一次token
							merPrinterService.getPrinterRefreshToken(printer.getId(), 1);
							//再次打印当前的单子
							printerAll(productOrder, mer, merTable, printer, listInfo);
						}

						//打印失败， 发送推送消息给商家管理员的公众号上
						//errorType  offline - 离线，  offpaper - 缺纸， offorder - 订单打印失败
//						wxTemplateService.sendWxMsgOfflineMerPrinter(printer,"offorder");
					}
//					orderMapper.updateById(productOrder);
				}
			}
		}
	}


	/**
	 * 后厨打印机打印订单
	 * @param productOrder
	 * @param mer
	 * @param merTable
	 * @param printer
	 * @param listInfo
	 */
	private void printerInfo(ProductOrder productOrder, Mer mer, MerTable merTable, MerPrinter printer, List<ProductOrderInfo> listInfo){
		if(printer != null){
			String content = getOrderInfoPrintContent(productOrder,mer,merTable,listInfo);
			String client_id = printer.getClientId();
			String access_token = merPrinterService.getPrinterAccessToken(printer.getId());
			String machine_code = printer.getDeviceSn();
			String origin_id = productOrder.getOrderNo();
			String uuid = LAVApi.getuuid();
			long timestamp = new Date().getTime() / 1000;
			//md5(client_id+push_time+client_secret)
			String sign = LAVApi.getSin(client_id , printer.getClientAppKey(),timestamp);

			//String client_id, String access_token, String machine_code, String content, String origin_id, String sign, String id, String timestamp
			String result = LAVApi.print(client_id, access_token, machine_code, content, origin_id, sign, uuid, String.valueOf(timestamp));
			if (result != null && !result.equals("")) {
				//{"error":"0","error_description":"success","body":{"id":"订单号","origin_id":""}}
				JSONObject jsonObject =  JSONUtil.parseObj(result);
				if (jsonObject != null) {
					int error = jsonObject.getInt("error");
					if(error == 0){
//						productOrder.setPrintState(1);
						System.out.println("打印成功");

						for(ProductOrderInfo info : listInfo){
							info.setPrintState(1);
							if(info.getPrintCount() == null){
								info.setPrintCount(1);
							}else{
								int printCount = info.getPrintCount();
								info.setPrintCount(printCount + 1);
							}
							productOrderInfoService.updateById(info);
						}
					}else{
						System.out.println("打印失败");
//						productOrder.setPrintState(2);

						for(ProductOrderInfo info : listInfo){
							info.setPrintState(2);
							productOrderInfoService.updateById(info);
						}
						if(error == 18){//token 失效
							//重新获取 一次token
							merPrinterService.getPrinterRefreshToken(printer.getId(), 1);
							//再次打印当前的单子
							printerInfo(productOrder, mer, merTable, printer, listInfo);
						}
						//打印失败， 发送推送消息给商家管理员的公众号上
						//errorType  offline - 离线，  offpaper - 缺纸， offorder - 订单打印失败
//						wxTemplateService.sendWxMsgOfflineMerPrinter(printer,"offorder");
					}
//					orderMapper.updateById(productOrder);
				}
			}
		}
	}


	private String getOrderPrintContent(ProductOrder productOrder, Mer mer, MerTable merTable, List<ProductOrderInfo> listInfo){
		String content =
			"<FH2><FS><FW> ******* " + mer.getShopName() + " ******* </FW></FS></FH2>\r\r\n" +
				"................................\r\n" +
//                "<FH2><FS><FW2>----货到付款----</FW2></FS></FH2>\\r\n" +
//                "<FH><center>测试营销2</center></FH>\\r\n" +
				"下单时间：" + DateUtils.date2Str(productOrder.getCreateTime(),"yyyy-MM-dd HH:mm:ss") + "\r\n" +
				"订单编号：" + productOrder.getOrderNo() + "\r\n" +
				"***************菜品*************\r\n\r\n" +
				"<FH2><center>--" + merTable.getTableName() + "--</center></FH2>\r\n" +
				"<FH><FW> \n";
		for(ProductOrderInfo infoDto : listInfo){
			String sku = infoDto.getSkuName();
			if(sku != null){
				if(sku.equals("默认")){
					sku = "";
				}
			}else{
				sku = "";
			}
			content += "<LR>" + infoDto.getProductName() + " " + sku + " ,<FW>x " + infoDto.getCount() + " ... "+infoDto.getSinglePrice() + "</FW></LR>\r\n\r\n";
		}
		content += "</FW></FH>\n" +
			"................................\r\n" +
			"********************************\n\n" +
//			"<FH2><FS><FW>\n" +
			"订单总价：￥" + MathUtil.getDoubleUp(productOrder.getTotalPrice().doubleValue()) + "\r\n" +
			"订单支付金额：￥" + MathUtil.getDoubleUp(productOrder.getPayPrice().doubleValue()) + "\r\n" +
			"客户备注：" + productOrder.getRemark() + "\r\n" +
//			"</FW></FS></FH2>\n" +
			"<FH2><FS><FW> **** 欢迎再次光临 **** </FW></FS></FH2>\n" +
			"\t\t\t\t\t\t\t\t";
		System.out.println(content);
		return content;
	}


	/**
	 * 后厨打印小单
	 * @param productOrder
	 * @param mer
	 * @param merTable
	 * @param listInfo
	 * @return
	 */
	public static String getOrderInfoPrintContent(ProductOrder productOrder, Mer mer, MerTable merTable, List<ProductOrderInfo> listInfo){
		String content =
			"<FH2><FS><FW> ******* " + mer.getShopName() +" ******* </FW></FS></FH2>\r\r\n" +
				"................................\r\n" +
//                "<FH2><FS><FW2>----货到付款----</FW2></FS></FH2>\\r\n" +
//                "<FH><center>测试营销2</center></FH>\\r\n" +
				"下单时间：" + DateUtils.date2Str(productOrder.getCreateTime(),"yyyy-MM-dd HH:mm:ss") + "\r\n" +
				"订单编号："+productOrder.getOrderNo()+"\r\n" +
				"***************菜品*************\r\n\r\n" +
				"<FH2><center>--" + merTable.getTableName() + "--</center></FH2>\r\n" +
				"<FH><FW> \n";
		for(ProductOrderInfo infoDto : listInfo){
			String sku = infoDto.getSkuName();
			if(sku != null){
				if(sku.equals("默认")){
					sku = "";
				}
			}else{
				sku = "";
			}
			content += "<LR>" + infoDto.getProductName() + " " + sku + " ,<FW>x" + infoDto.getCount() + " ... "+infoDto.getSinglePrice() + "</FW></LR>\r\n\r\n";
		}
		content += "</FW></FH>\n" +
			"................................\r\n" +
			"********************************" +
//			"<FH>\n" +
			"订单总价：￥" + MathUtil.getDoubleUp(productOrder.getTotalPrice().doubleValue()) + "\r\n" +
			"订单支付金额：￥" + MathUtil.getDoubleUp(productOrder.getPayPrice().doubleValue()) + "\r\n" +
			"客户备注：" + productOrder.getRemark() + "\r\n" +
//			"</FH>\n" +
//			"<FH2><FS><FW> **** 欢迎再次光临 **** </FS></FW></FH2>\n" +
			"\t\t\t\t\t\t\t\t";
		return content;
	}
}
